home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH12 / EX12_3.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-02-22  |  8.3 KB  |  436 lines

  1. ; EX12_3.asm
  2. ;
  3. ; Ex12_3.asm
  4. ;
  5. ; This program demonstrates different parameter passing methods.  
  6. ; It corresponds to the following (pseudo) Pascal code:
  7. ;
  8. ;
  9. ; program main;
  10. ; var    i:integer;
  11. ;    a:array[0..255] of integer;
  12. ;    b:array[0..255] of unsigned;
  13. ;
  14. ; function LTint(int1, int2:integer):boolean;
  15. ; begin
  16. ;    LTint := int1 < int2;
  17. ; end;
  18. ;
  19. ; procedure SwapInt(var int1, int2:integer);
  20. ; var temp:integer;
  21. ; begin
  22. ;    temp := int1;
  23. ;    int1 := int2;
  24. ;    int2 := temp;
  25. ; end;
  26. ;
  27. ; function LTunsigned(uns1, uns2:unsigned):boolean;
  28. ; begin
  29. ;    LTunsigned := uns1 < uns2;
  30. ; end;
  31. ;
  32. ; procedure SwapUnsigned(uns1, uns2:unsigned);
  33. ; var temp:unsigned;
  34. ; begin
  35. ;    temp := uns1;
  36. ;    uns1 := uns2;
  37. ;    uns2 := temp;
  38. ; end;
  39. ;
  40. ; (* The following is a simple Bubble sort that will sort arrays containing *)
  41. ; (* arbitrary data types.                                                  *)
  42. ;
  43. ; procedure sort(data:array; elements:integer; function LT:boolean; procedure swap);
  44. ; var i,j:integer;
  45. ; begin
  46. ;
  47. ;    for i := 0 to elements-1 do
  48. ;        for j := i+1 to elements do
  49. ;        if (LT(data[j], data[i])) then swap(data[i], data[j]);
  50. ; end;
  51. ;
  52. ;
  53. ; begin
  54. ;
  55. ;    for i := 0 to 255 do A[i] := 128-i;
  56. ;    for i := 0 to 255 do B[i] := 33000-i;
  57. ;    sort(A, 256, LTint, SwapInt);
  58. ;    sort(B, 256, LTunsigned, SwapUnsigned);
  59. ;
  60. ;    for i := 0 to 255 do
  61. ;    begin
  62. ;        if (i mod 8) = 0 then writeln;
  63. ;        write(A[i]:7);
  64. ;    end;
  65. ;
  66. ;    for i := 0 to 255 do
  67. ;    begin
  68. ;        if (i mod 8) = 0 then writeln;
  69. ;        write(B[i]:7);
  70. ;    end;
  71. ;
  72. ; end;
  73.  
  74.         .xlist
  75.         include     stdlib.a
  76.         includelib    stdlib.lib
  77.         .list
  78.  
  79.         .386
  80.         option        segment:use16
  81.  
  82. wp        textequ        <word ptr>
  83.  
  84.  
  85. dseg        segment    para public 'data'
  86. A        word    256 dup (?)
  87. B        word    256 dup (?)
  88. dseg        ends
  89.  
  90.  
  91.  
  92. cseg        segment    para public 'code'
  93.         assume    cs:cseg, ds:dseg, ss:sseg
  94.  
  95.  
  96. ; function LTint(int1, int2:integer):boolean;
  97. ; begin
  98. ;    LTint := int1 < int2;
  99. ; end;
  100. ;
  101. ; LTint's activation record looks like this:
  102. ;
  103. ;    |----------------|
  104. ;    |      int1      |
  105. ;    |----------------|
  106. ;    |      int2      |
  107. ;    |----------------|
  108. ;    | return address |
  109. ;    |----------------|
  110. ;    |    old BP      |<- SP, BP
  111. ;    |----------------|
  112.  
  113. int1        textequ    <word ptr [bp+6]>
  114. int2        textequ    <word ptr [bp+4]>
  115.  
  116. LTint        proc    near
  117.         push    bp
  118.         mov    bp, sp
  119.         
  120.         mov    ax, int1    ;Compare the two parameters
  121.         cmp    ax, int2    ; and return true if int1<int2.
  122.         setl    al        ;Signed comparison here.
  123.         mov    ah, 0        ;Be sure to clear H.O. byte.
  124.  
  125.         pop    bp
  126.         ret    4
  127. LTint        endp
  128.  
  129.  
  130. ; Swap's activation record looks like this:
  131. ;
  132. ;    |----------------|
  133. ;    |     Address    |
  134. ;    |---    of    ---|
  135. ;    |      int1      |
  136. ;    |----------------|
  137. ;    |     Address    |
  138. ;    |---    of    ---|
  139. ;    |      int2      |
  140. ;    |----------------|
  141. ;    | return address |
  142. ;    |----------------|
  143. ;    |    old BP      |<- SP, BP
  144. ;    |----------------|
  145. ;
  146. ; The temporary variable is kept in a register.
  147. ;
  148. ; Note that swapping integers or unsigned integers can be done
  149. ; with the same code since the operations are identical for
  150. ; either type.
  151. ;
  152. ; procedure SwapInt(var int1, int2:integer);
  153. ; var temp:integer;
  154. ; begin
  155. ;    temp := int1;
  156. ;    int1 := int2;
  157. ;    int2 := temp;
  158. ; end;
  159. ;
  160. ; procedure SwapUnsigned(uns1, uns2:unsigned);
  161. ; var temp:unsigned;
  162. ; begin
  163. ;    temp := uns1;
  164. ;    uns1 := uns2;
  165. ;    uns2 := temp;
  166. ; end;
  167. ;
  168.  
  169. int1        textequ    <dword ptr [bp+8]>
  170. int2        textequ    <dword ptr [bp+4]>
  171.  
  172. SwapInt        proc    near
  173.         push    bp
  174.         mov    bp, sp
  175.         push    es
  176.         push    bx
  177.  
  178.         les    bx, int1        ;Get address of int1 variable.
  179.         mov    ax, es:[bx]        ;Get int1's value.
  180.         les    bx, int2        ;Get address of int2 variable.
  181.         xchg    ax, es:[bx]        ;Swap int1's value with int2's
  182.  
  183.         les    bx, int1        ;Get the address of int1 and
  184.         mov    es:[bx], ax        ; store int2's value there.
  185.  
  186.         pop    bx
  187.         pop    es
  188.         pop    bp
  189.         ret    8
  190. SwapInt        endp
  191.  
  192.  
  193.  
  194. ; LTunsigned's activation record looks like this:
  195. ;
  196. ;    |----------------|
  197. ;    |      uns1      |
  198. ;    |----------------|
  199. ;    |      uns2      |
  200. ;    |----------------|
  201. ;    | return address |
  202. ;    |----------------|
  203. ;    |    old BP      |<- SP, BP
  204. ;    |----------------|
  205. ;
  206. ; function LTunsigned(uns1, uns2:unsigned):boolean;
  207. ; begin
  208. ;    LTunsigned := uns1 < uns2;
  209. ; end;
  210.  
  211. uns1        textequ    <word ptr [bp+6]>
  212. uns2        textequ    <word ptr [bp+4]>
  213.  
  214. LTunsigned    proc    near
  215.         push    bp
  216.         mov    bp, sp
  217.         
  218.         mov    ax, uns1    ;Compare uns1 with uns2 and
  219.         cmp    ax, uns2    ; return true if uns1<uns2.
  220.         setb    al        ;Unsigned comparison.
  221.         mov    ah, 0        ;Return 16-bit boolean.
  222.  
  223.         pop    bp
  224.         ret    4
  225. LTunsigned    endp
  226.  
  227.  
  228.  
  229. ; Sort's activation record looks like this:
  230. ;
  231. ;    |----------------|
  232. ;    |     Data's     |
  233. ;    |---          ---|
  234. ;    |    Address     |
  235. ;    |----------------|
  236. ;    |   Elements     |
  237. ;    |----------------|
  238. ;    |      LT's      |
  239. ;    |---          ---|
  240. ;    |    Address     |
  241. ;    |----------------|
  242. ;    |     Swap's     |
  243. ;    |---          ---|
  244. ;    |    Address     |
  245. ;    |----------------|
  246. ;    | return address |
  247. ;    |----------------|
  248. ;    |    old BP      |<- SP, BP
  249. ;    |----------------|
  250. ;
  251. ; procedure sort(data:array; elements:integer; function LT:boolean; procedure swap);
  252. ; var i,j:integer;
  253. ; begin
  254. ;
  255. ;    for i := 0 to elements-1 do
  256. ;        for j := i+1 to elements do
  257. ;        if (LT(data[j], data[i])) then swap(data[i], data[j]);
  258. ; end;
  259.  
  260.  
  261. data        textequ    <dword ptr [bp+10]>
  262. elements    textequ    <word ptr [bp+8]>
  263. funcLT        textequ    <word ptr [bp+6]>
  264. procSwap    textequ    <word ptr [bp+4]>
  265.  
  266. i        textequ    <word ptr [bp-2]>
  267. j        textequ    <word ptr [bp-4]>
  268.  
  269. sort        proc    near
  270.         push    bp
  271.         mov    bp, sp
  272.         sub    sp, 4
  273.         push    es
  274.         push    bx
  275.  
  276.         mov    i, 0
  277. ForILp:        mov    ax, i            ;Compare with elements-1.
  278.         inc    ax            ;Do this by incrementing I
  279.         cmp    ax, Elements        ; and comparing with Elements.
  280.         jae    IDone
  281.  
  282.         mov    j, ax            ;Put i+1 into J.
  283. ForJLp:        mov    ax, j
  284.         cmp    ax, Elements
  285.         jae    JDone
  286.  
  287.         les    bx, data        ;Push the value of
  288.         mov    si, j            ; data[j] onto the
  289.         add    si, si            ; stack.
  290.         push    es:[bx+si]
  291.  
  292.         les    bx, data        ;Push the value of
  293.         mov    si, i            ; data[i] onto the
  294.         add    si, si            ; stack.
  295.         push    es:[bx+si]
  296.  
  297.         call    FuncLT            ;See if data[i] < data[j]
  298.         cmp    ax, 0            ;Test boolean result.
  299.         je    NextJ
  300.  
  301.         push    wp data+2        ;Pass data[i] by reference.
  302.         mov    ax, i
  303.         add    ax, ax
  304.         add    ax, wp data
  305.         push    ax
  306.  
  307.         push    wp data+2        ;Pass data[j] by reference.
  308.         mov    ax, j
  309.         add    ax, ax
  310.         add    ax, wp data
  311.         push    ax
  312.  
  313.         call    ProcSwap
  314.  
  315. NextJ:        inc    j
  316.         jmp    ForJLp
  317.  
  318. JDone:        inc    i
  319.         jmp    ForILp
  320.  
  321. IDone:        pop    bx
  322.         pop    es
  323.         mov    sp, bp
  324.         pop    bp
  325.         ret    10
  326. sort        endp
  327.  
  328.  
  329.  
  330.  
  331.         
  332. ; Main's activation record looks like this:
  333. ;
  334. ;    | return address |<- SP, BP
  335. ;    |----------------|
  336. ;
  337. ; begin
  338. ;
  339. ;    for i := 0 to 255 do A[i] := 128-i;
  340. ;    for i := 0 to 255 do B[i] := 33000-i;
  341. ;    sort(A, 256, LTint, SwapInt);
  342. ;    sort(B, 256, LTunsigned, SwapUnsigned);
  343. ;
  344. ;    for i := 0 to 255 do
  345. ;    begin
  346. ;        if (i mod 8) = 0 then writeln;
  347. ;        write(A[i]:7);
  348. ;    end;
  349. ;
  350. ;    for i := 0 to 255 do
  351. ;    begin
  352. ;        if (i mod 8) = 0 then writeln;
  353. ;        write(B[i]:7);
  354. ;    end;
  355. ;
  356. ; end;
  357.  
  358. Main        proc
  359.         mov    ax, dseg    ;Initialize the segment registers.
  360.         mov    ds, ax
  361.         mov    es, ax
  362.  
  363. ; Note that the following code merges the two initialization for loops
  364. ; into a single loop.
  365.  
  366.         mov    ax, 128
  367.         mov    bx, 0
  368.         mov    cx, 33000
  369. ForILp:        mov    A[bx], ax
  370.         mov    B[bx], cx
  371.         add    bx, 2
  372.         dec    ax
  373.         dec    cx
  374.         cmp    bx, 256*2
  375.         jb    ForILp
  376.  
  377.         push    ds            ;Seg address of A
  378.         push    offset A        ;Offset of A
  379.         push    256            ;# of elements in A
  380.         push    offset LTint        ;Address of compare routine
  381.         push    offset SwapInt        ;Address of swap routine
  382.         call    Sort
  383.  
  384.  
  385.         push    ds            ;Seg address of B
  386.         push    offset B        ;Offset of B
  387.         push    256            ;# of elements in A
  388.         push    offset LTunsigned    ;Address of compare routine
  389.         push    offset SwapInt        ;Address of swap routine
  390.         call    Sort
  391.  
  392. ; Print the values in A.
  393.  
  394.         mov    bx, 0
  395. ForILp2:    test    bx, 0Fh            ;See if (I mod 8) = 0
  396.         jnz    NotMod            ; note: BX mod 16 = I mod 8.
  397.         putcr
  398. NotMod:        mov    ax, A[bx]
  399.         mov    cx, 7
  400.         putisize
  401.         add    bx, 2
  402.         cmp    bx, 256*2
  403.         jb    ForILp2
  404.  
  405. ; Print the values in B.
  406.  
  407.         putcr
  408.  
  409.         mov    bx, 0
  410. ForILp3:    test    bx, 0Fh            ;See if (I mod 8) = 0
  411.         jnz    NotMod2            ; note: BX mod 16 = I mod 8.
  412.         putcr
  413. NotMod2:    mov    ax, B[bx]
  414.         mov    cx, 7
  415.         putusize
  416.         add    bx, 2
  417.         cmp    bx, 256*2
  418.         jb    ForILp3
  419.  
  420. Quit:        ExitPgm            ;DOS macro to quit program.
  421. Main        endp
  422.  
  423.  
  424.  
  425. cseg            ends
  426.  
  427.  
  428. sseg        segment    para stack 'stack'
  429. stk        word    256 dup (0)
  430. sseg        ends
  431.  
  432. zzzzzzseg    segment    para public 'zzzzzz'
  433. LastBytes    db    16 dup (?)
  434. zzzzzzseg    ends
  435.         end    Main
  436.